import type { Menu } from '/@/api/model/baseModel';

import { toRaw } from 'vue';
import { RouteRecordRaw } from 'vue-router';
import { asyncRoutes } from '/@/router/routes';
import { defineStore } from 'pinia';
import { useUserStore } from './user';
import { transformObjToRoute, flatMultiLevelRoutes, addSlashToRouteComponent } from '/@/router/support/routeHelper';
import { transformRouteToMenu } from '/@/router/support/menuHelper';
import { filter } from '/@/utils/helper/treeHelper';
import { PageEnum, } from '/@/common/enums/sysEnum';
import { getBackMenuAndPerms } from '/@/api/common/sys';
import sysSet from '/@/settings/sysSetting';

// 系统权限
interface AuthItem {
  // 菜单权限编码，例如：“sys:schedule:list,sys:schedule:info”,多个逗号隔开
  action: string;
  // 权限策略1显示2禁用
  type: string | number;
  // 权限状态(0无效1有效)
  status: string | number;
  // 权限名称
  describe?: string;
  isAuth?: boolean;
}

interface PermissionState {
  // Permission code list
  permCodeList: string[] | number[];
  // Whether the route has been dynamically added
  isDynamicAddedRoute: boolean;
  // To trigger a menu update
  lastBuildMenuTime: number;
  // Backstage menu list
  backMenuList: Menu[];
  frontMenuList: Menu[];
  // 用户所拥有的功能权限-按钮等
  authList: AuthItem[];
  // 全部权限配置
  allAuthList: AuthItem[];
  // 系统安全模式
  sysSafeMode: boolean;
  // online子表按钮权限
  onlineSubTableAuthMap: object;
}
export const usePermissionStore = defineStore({
  id: 'app-permission',
  state: (): PermissionState => ({
    permCodeList: [],
    isDynamicAddedRoute: false,     //是否为动态路由添加
    // To trigger a menu update
    lastBuildMenuTime: 0,
    // Backstage menu list
    backMenuList: [],
    // menu List
    frontMenuList: [],
    authList: [],
    allAuthList: [],
    sysSafeMode: false,
    onlineSubTableAuthMap: {},
  }),
  getters: {
    getPermCodeList(): string[] | number[] {
      return this.permCodeList;
    },
    getBackMenuList(){
      return this.backMenuList;
    },
    getFrontMenuList(): Menu[] {
      return this.frontMenuList;
    },
    getLastBuildMenuTime(): number {
      return this.lastBuildMenuTime;
    },
    getIsDynamicAddedRoute(): boolean {
      return this.isDynamicAddedRoute;
    },
    //子表按钮没控制
    getOnlineSubTableAuth: (state) => {
      return (code) => state.onlineSubTableAuthMap[code];
    },
  },
  actions: {
    setPermCodeList(codeList: string[]) {
      this.permCodeList = codeList;
    },
    setBackMenuList(list) {
      this.backMenuList = list;
      list?.length > 0 && this.setLastBuildMenuTime();
    },
    setFrontMenuList(list) {
      this.frontMenuList = list;
    },
    setLastBuildMenuTime() {
      this.lastBuildMenuTime = new Date().getTime();
    },
    setDynamicAddedRoute(added: boolean) {
      this.isDynamicAddedRoute = added;
    },
    setAuthData(systemPermission) {
      this.authList = systemPermission.button;
      this.allAuthList = systemPermission.allButton;
      this.sysSafeMode = systemPermission.sysSafeMode;
    },
    setAuthList(authList: AuthItem[]) {
      this.authList = authList;
    },
    setAllAuthList(authList: AuthItem[]) {
      this.allAuthList = authList;
    },
    //update-begin-author:taoyan date:2022-6-1 for: VUEN-1162 子表按钮没控制
    setOnlineSubTableAuth(code, hideBtnList) {
      this.onlineSubTableAuthMap[code] = hideBtnList;
    },
    resetState(): void {
      this.isDynamicAddedRoute = false;
      this.permCodeList = [];
      this.backMenuList = [];
      this.lastBuildMenuTime = 0;
    },
    //获取菜单和按钮
    async getMenuAndBtn() {
      const auth = await getBackMenuAndPerms();
      this.setAuthData(auth);
      this.setPermCodeList(auth.buttonCodeList);
      //菜单路由
      const routeList = auth.menu;
      return routeList;
    },
    //构建菜单
    async buildMenu(): Promise<RouteRecordRaw[]> {
      // debugger
      const userStore = useUserStore();
      let routes: RouteRecordRaw[] = [];
      const roleList = toRaw(userStore.getRoleList) || [];

      /**
       * 过滤角色权限
       */
      const routeFilter = (route: RouteRecordRaw) => {
        const { meta } = route;
        const { roles } = meta || {};
        if (!roles) return true;
        return roleList.some((role) => roles.includes(role));
      };

      /**
       * 过滤忽略路由
       */
      const routeRemoveIgnoreFilter = (route: RouteRecordRaw) => {
        const { meta } = route;
        const { ignoreRoute } = meta || {};
        return !ignoreRoute;
      };

      /**
       * 固定首页affix标记
       */
      const patchHomeAffix = (routes: RouteRecordRaw[]) => {
        // debugger
        if (!routes || routes.length === 0) return;
        let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME;
        function patcher(routes: RouteRecordRaw[], parentPath = '') {
          if (parentPath) parentPath = parentPath + '/';
          routes.forEach((route: RouteRecordRaw) => {
            const { path, children, redirect } = route;
            const currentPath = path.startsWith('/') ? path : parentPath + path;
            if (currentPath === homePath) {
              if (redirect) {
                homePath = route.redirect! as string;
              } else {
                route.meta = Object.assign({}, route.meta, { affix: true });
                throw new Error('end');
              }
            }
            children && children.length > 0 && patcher(children, currentPath);
          });
        }
        try {
          patcher(routes);
        } catch (e) {
          // 已处理完毕跳出循环
        }
        return;
      };

      const menuMode = sysSet.permissionMode;
      switch (menuMode) {
        case 3:
          console.log(" --- 构建路由菜单-角色模式 --- ")
          routes = asyncRoutes;
          //  将多级路由转换为二级
          routes = flatMultiLevelRoutes(routes);
          break;
        case 2:
          console.log(" --- 构建路由菜单-前端模式 --- ")
          routes = asyncRoutes;
          const menuList = transformRouteToMenu(routes, true);
          routes = filter(routes, routeRemoveIgnoreFilter);
          routes = routes.filter(routeRemoveIgnoreFilter);
          //排序
          menuList.sort((a, b) => {
            return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0);
          });
          this.setFrontMenuList(menuList);
          // 将多级路由转换为二级
          routes = flatMultiLevelRoutes(routes);
          break;
        case 1:
          console.log(" --- 构建路由菜单-后台模式 --- ")
          let routeList = await this.getMenuAndBtn();
          // 组件地址前加斜杠处理  author: lsq date:2021-09-08
          routeList = addSlashToRouteComponent(routeList);
          // 路由组件原始封装
          routeList = transformObjToRoute(routeList);
          // 构建后台路由菜单
          const backMenuList = transformRouteToMenu(routeList);
          this.setBackMenuList(backMenuList);
          // 删除meta.ignoreRoute项
          routeList = filter(routeList, routeRemoveIgnoreFilter);
          routeList = routeList.filter(routeRemoveIgnoreFilter);
          routeList = flatMultiLevelRoutes(routeList);
          routes = [...routeList,];
          break;
      }
      patchHomeAffix(routes);
      return routes;
    },
  },
});
